package client;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.SocketException;

import util.Logger;

import UI.UI;
import dataContracts.Command;
import dataContracts.SharedFile;

public class MessageHandler {
	public ClientProgram program;
	public UI ui;
	
	MessageHandler(ClientProgram program) {
		this.program = program;
	}
	
	public void AddLogMsg(String msg) {
		ui.servLog(msg);
	}
	
	public void RequestSynch() {
		sendCommand(Command.Type.Synch);
	}
	
	public void RequestUpload(String file) {
		sendCommand(Command.Type.RecvFile, file);
	}
	
	public void GetFile(String fileName) {
		sendCommand(Command.Type.GetFile, fileName);
	}
	
	public void PrepareForDirectoryObject() {
		sendCommand(Command.Type.PrepareForDirectoryObject);
	}
	
	public void registerWithServer() {
		sendCommand(Command.Type.Register, program.settings.userName);
	}
	
	public void disconnectClient() {
		// disconnect from the server, clean up, etc.
		program.disconnect();
	}

	public class Broadcast implements ActionListener	{
		@Override
		public void actionPerformed(ActionEvent arg0) {
			sendCommand(Command.Type.Broadcast, UI.builder.broadcastText.getText());
			UI.builder.broadcastText.setText("");
		}
	}
	
	public class IsEqual implements ActionListener	{
		@Override
		public void actionPerformed(ActionEvent arg0) {
			program.directory.refresh();
			redrawUI();
			sendCommand(Command.Type.IsEqual, program.directory.getChecksum());
		}
	}
	
	public class Connect implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			//BEN TO INSERT SOME stuff
			if (!program.isConnected()) {
				program.connect();
			}
		}
	}
	
	private void sendCommand(Command.Type type) {
		sendCommand(type, "");
	}
	
	private void sendCommand(Command.Type type, String command) {
		if (!program.isConnected()) {
			Logger.Warning("Disconnected from server...");
			program.connect();
			return;
		}
		
		try {
			Command c = new Command(type, command, program.directory);
			program.objectWriter.writeObject(c);
			program.objectWriter.flush();
			program.objectWriter.reset();
		} catch(SocketException eof) {
			Logger.Debug("disconnected from server");
			program.disconnect();
			program.connect();
			
		} catch (IOException e) {
			Logger.Debug("Can't send message: "+ e.toString());
		}
	}
	
	public void deleteFile(String name) {
		// find the file object in the directory (what do do if we can't find it?)
		SharedFile file = program.directory.findFile(name);
		// this marks it as removed, and then synchs with the server to finalize
		program.directory.removeFile(name);
		// tell the server to remove it there, to keep synching in real-time
		sendCommand(Command.Type.DeleteFile, file.getName());
	}
	
	public void addFile(String name) {
		// find the file object in the directory (what do do if we can't find it?)
		try {
			program.directory.addFile(name);
		} catch (FileNotFoundException e) { /* do nothing, trust file exists or this wouldn't be invoked */ }
		
		// this marks it as removed, and then synchs with the server to finalize
		sendCommand(Command.Type.RecvFile, name);
	}

	public void saveAttributes(SharedFile sf) {
		sf.saveAttributes();
		program.directory.SaveChanges();
	}
	
	public void redrawUI() {
		ui.builder.redrawLeftPane();
	}
}
